﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace SangoBang
{
    using Cards;
    using Cards.Characters;
    class Game
    {
        public Game() 
        {
            mGameCardFull = new GameCard[70];
            GameCard kill = new GameCard("Kill");
            GameCard miss = new GameCard("Miss");
            GameCard cure = new GameCard("Cure");
            int i = 0;
            for (; i < 40; i++) 
            {
                mGameCardFull[i] = kill;
            }
            for (; i < 60; i++)
            {
                mGameCardFull[i] = miss;
            }
            for (; i < 70; i++) 
            {
                mGameCardFull[i] = cure; 
            }

        }
        public void AddPlayer(Player player) 
        {
            player.Game = this;
            lock (mPlayerList)
            {
                if (mPlayerList.Count != 0)
                {
                    mPlayerList.Last().Next = player;
                }
                mPlayerList.Add(player);
                player.Next = mPlayerList[0];
            }
        }
		public void RemovePlayer(Player player)
		{
            player.Game = null;
			lock(mPlayerList)
			{
				mPlayerList.Remove(player);
			}
		}
        public Player GetPlayer(string username) 
        {
            IEnumerable<Player> playerQuery = from player in mPlayerList
                                              where player.mName == username
                                              select player;
          
            foreach (Player player in playerQuery)
            {
                return player;
            }
            return null;
        }

        private RoleCard[] roleCardFull = new RoleCard[]{
            new RoleCard("P Zhugong"),
            new RoleCard("P Zhongchen"),
            new RoleCard("N Fanzei"),
            new RoleCard("A Neijian"),
            new RoleCard("N Fanzei"),
            new RoleCard("N Fanzei"),
            new RoleCard("P Zhongchen"),
            new RoleCard("N Fanzei"),
            new RoleCard("P Zhongchen"),
            new RoleCard("A Neijian"),
        };
        private CharacterCard[] characterCardFull = new CharacterCard[]{
            new CharacterCard(CharacterEnum.Caocao),
            new CharacterCard(CharacterEnum.Liubei),
            new CharacterCard(CharacterEnum.Lvbu),
            new CharacterCard(CharacterEnum.Sunquan),
            new CharacterCard(CharacterEnum.Taishici),
            new CharacterCard(CharacterEnum.Xiahoudun),
            new CharacterCard(CharacterEnum.Xuzhu),
            new CharacterCard(CharacterEnum.Zhangfei),
            new CharacterCard(CharacterEnum.Zhouyu),
            new CharacterCard(CharacterEnum.Zhugeliang)
        };
        private GameCard[] mGameCardFull = null;
        
        public void DealRole() 
        {
            int playerNum = mPlayerList.Count;
            RoleCard[] roleCards = new RoleCard[playerNum];
            int i = 0;
            for (i = 0; i < playerNum; ++i) {
                roleCards[i] = roleCardFull[i];
            }
            Shuffle(roleCards);
            for (i = 0; i < playerNum; ++i) {
                mPlayerList[i].mRole = roleCards[i].ToString();
            }
        }
        public void DealCharacter()
        {
            int playerNum = mPlayerList.Count;
            int characterNum = characterCardFull.Length;
            CharacterCard[] characterCards = new CharacterCard[characterNum];
            int i = 0;
            for (i = 0; i < characterNum; ++i)
            {
                characterCards[i] = characterCardFull[i];
            }
            Shuffle(characterCards);
            for (i = 0; i < playerNum; ++i)
            {
                mPlayerList[i].mCharacterName = characterCards[i].mCharacterEnum.ToString();
                mPlayerList[i].mCharacter = Character.sCharacterDict[characterCards[i].mCharacterEnum];
                mPlayerList[i].HP = Character.sCharacterDict[characterCards[i].mCharacterEnum].mHitPoint;
            }
        }

        public void ResetResource()
        {
            DealRole();
            DealCharacter();
        }

        private void Shuffle(RoleCard[] cards)
        {
            int size = cards.Length;
            Random rand = new Random();
            int i = size - 1;
            for (; i > 0; i--) {
                int j = rand.Next(i);
                RoleCard temp = cards[i];
                cards[i] = cards[j];
                cards[j] = temp;
            }
        }
        private void Shuffle(CharacterCard[] cards)
        {
            int size = cards.Length;
            Random rand = new Random();
            int i = size - 1;
            for (; i > 0; i--)
            {
                int j = rand.Next(i);
                CharacterCard temp = cards[i];
                cards[i] = cards[j];
                cards[j] = temp;
            }
        }
        private void Shuffle(GameCard[] cards)
        {
            int size = cards.Length;
            Random rand = new Random();
            int i = size - 1;
            for (; i > 0; i--)
            {
                int j = rand.Next(i);
                GameCard temp = cards[i];
                cards[i] = cards[j];
                cards[j] = temp;
            }
        }
        public List<Player> mPlayerList = new List<Player>();


        public void StartGame()
        {
            DealRole();
            DealCharacter();
            DealGameCard();
        }
        private Queue<GameCard> mGameCardQueue = null;
       
        private void DealGameCard()
        {
            Shuffle(mGameCardFull);
            mGameCardQueue = new Queue<GameCard>(mGameCardFull);
        }
        public GameCard GetGameCard() 
        {
            GameCard card = mGameCardQueue.Dequeue();
            if (mGameCardQueue.Count == 0) {
                DealGameCard();
            }
            return card;
        }
    }
}
